<script lang="tsx">
import { defineComponent, type PropType, unref } from 'vue';
import type { PaginationProps } from 'element-plus';
import type { PaginationPropsType } from '../types/pagination';
import {
  cloneDeep,
  get,
  has,
  isBoolean,
  isFunction,
  isNull,
  isString,
  isUndefined,
} from 'lodash-es';
import type { BasicColumn, BasicTableProps } from '../types/table';
import { VxeColgroup, VxeColumn } from 'vxe-table';
export default defineComponent({
  name: 'VxeTableColumn',
  props: {
    getColumnsRef: {
      type: Array as PropType<BasicColumn[]>,
      default: () => [],
    },
    getTableProps: {
      type: Object as PropType<BasicTableProps>,
      default: () => {},
    },
    getPaginationInfo: {
      type: [Object, Boolean] as PropType<PaginationProps | PaginationPropsType | boolean>,
    },
    setProps: {
      type: Function as PropType<(arg: Partial<BasicTableProps>) => void>,
      default: null,
    },
  },
  setup(props, { slots }) {
    let slotsd: any = slots;

    // 多级表头
    function RenderTableColgroup(columnsChildren?: BasicColumn | any) {
      const children = columnsChildren?.children;
      const oneData = cloneDeep(columnsChildren);
      delete oneData.children;
      return <VxeColgroup {...oneData}>{RenderTableColumn(children)}</VxeColgroup>;
    }
    // 表格column
    function RenderTableColumn(columnsChildren?: BasicColumn[]) {
      const { align, headerAlign, showIndexColumn } = unref(props.getTableProps);
      return (columnsChildren || props.getColumnsRef).map((v: BasicColumn) => {
        if (has(v, 'ifShow')) {
          if (isBoolean(v.ifShow) && !v.ifShow) return null;
          if (isFunction(v.ifShow) && !v.ifShow(v)) return null;
        }
        const typeWidth = '5%';
        const field = (v.dataIndex || v.field) as string;
        // 序号
        if (v.type == 'seq' && showIndexColumn) {
          return (
            <VxeColumn
              type="seq"
              width={typeWidth}
              align={v.align || align}
              headerAlign={v.headerAlign || headerAlign}
              field={field}
              {...v}
            ></VxeColumn>
          );
        } else if (v.type === 'checkbox') {
          //复选框

          return (
            <VxeColumn
              width={typeWidth}
              align={v.align || align}
              headerAlign={v.headerAlign || headerAlign}
              field={field}
              {...v}
            ></VxeColumn>
          );
        } else if (v.type === 'radio') {
          //单选框
          const setSlot: any = {
            default: (...args: any[]) => {
              const data = args[0];
              let value = get(data.row, field as string);
              let valued = '';
              if (isUndefined(field)) {
                valued = '';
              } else if (isUndefined(value) || isNull(value)) {
                valued = '--';
              } else {
                valued = value;
              }
              return valued;
            },
          };
          return (
            <VxeColumn
              type="radio"
              width={typeWidth}
              align={v.align || align}
              headerAlign={v.headerAlign || headerAlign}
              {...v}
            >
              {setSlot}
            </VxeColumn>
          );
        } else {
          const getOne = { ...v } as any;
          if (getOne.children) {
            // 多级表头
            return RenderTableColgroup(getOne);
          }
          const showOverflow = !isUndefined(v.showOverflow) ? v.showOverflow : 'tooltip';
          // 删除多余字段
          if (has(getOne, 'dataIndex')) {
            delete getOne.dataIndex;
          }
          if (has(getOne, 'title')) {
            delete getOne.title;
          }
          let setSlot: any = {};
          // 头部插槽
          if (has(getOne, 'headerRender') || has(getOne, 'headerSlot')) {
            setSlot = {
              ...setSlot,
              header: (data: any) => {
                if (has(getOne, 'headerRender')) {
                  return getOne.headerRender(data);
                } else if (
                  has(getOne, 'headerSlot') &&
                  !isUndefined(slotsd[(getOne as any)?.headerSlot])
                ) {
                  return slotsd[(getOne as any)?.headerSlot](data);
                }
              },
            };
          }
          if (v?.formatter || v?.cellRender) {
          } else {
            // 插槽模式
            setSlot = {
              ...setSlot,
              default: (...args: any[]) => {
                const data = args[0];
                if (!isUndefined(slotsd[field]) && slotsd[field] && isString(v.dataIndex)) {
                  return slotsd[field]({
                    row: data.row,
                    column: data.column,
                    cellValue: get(data.row, v.dataIndex as string),
                    index: data.$index,
                  });
                } else if (v?.customRender) {
                  return v?.customRender?.({
                    row: data.row,
                    column: data.column,
                    cellValue: get(data.row, v.dataIndex as string),
                    index: data.$index,
                  });
                } else {
                  let value = get(data.row, v.dataIndex as string);
                  return isUndefined(value) || isNull(value) ? '--' : value;
                }
              },
              content: (...args: any[]) => {
                const data = args[0];
                if (has(getOne, 'expandSlot')) {
                  return slotsd[(getOne as any)?.expandSlot](data);
                } else if (v?.expandRender) {
                  return v?.expandRender?.(data);
                }
              },
            };
          }
          return (
            <VxeColumn
              {...getOne}
              show-overflow={showOverflow}
              align={v.align || align}
              headerAlign={v.headerAlign || headerAlign}
              field={field}
              title={v.title}
            >
              {setSlot}
            </VxeColumn>
          );
        }
      });
    }
    return () => {
      return <>{RenderTableColumn()}</>;
    };
  },
});
</script>
<style></style>
